home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Gold Collection
/
Software Vault - The Gold Collection (American Databankers) (1993).ISO
/
cdr10
/
tvprompt.zip
/
READER.PKG
< prev
next >
Wrap
Text File
|
1992-05-29
|
4KB
|
121 lines
with Command_Line,
DOS_IO,
Screen;
-- Copyright 1991,92 Tom Moran
package body Reader is
task body Read_File is
Patience: Duration := 0.0;
subtype Printable_Chars is Character range ' ' .. '~';
subtype Visible_Chars is Character range '!' .. '~';
Char : Character;
The_Line: Screen.Scrollable_Strings;
F : DOS_IO.File_Handle;
Ctrl_Z : constant Character := Ascii.Sub;
Max_Back_Off: constant := 10; -- max back up looking for word break
subtype Buffer_Indices is Integer range 1 .. 256 + Max_Back_Off;
Buffer : String(Buffer_Indices);
Read_Count: Natural;
Current_Char_Index: Integer
range Buffer_Indices'First .. Buffer_Indices'Last + 1
:= Buffer_Indices'Last + 1;
Last_Char_Index: Integer
range Buffer_Indices'First - 1 .. Buffer_Indices'Last
:= Buffer_Indices'First - 1;
begin
accept Start_Up;
if Command_Line.Parameter_Count = 1 then
DOS_IO.Open(Command_Line.Parameter(1), F);
end if;
Reading_Lines:
loop
The_Line := " ";
exit Reading_Lines when not DOS_IO.Is_Open(F);
Reading_Characters:
for I in The_Line'range loop
if Current_Char_Index > Last_Char_Index then
Current_Char_Index := Buffer'First + Max_Back_Off;
Read_Count := Integer(DOS_IO.Read(F, Buffer(Current_Char_Index)'
Address, DOS_IO.Byte_Counts(Buffer'Length - Max_Back_Off)));
if Read_Count = 0 then
DOS_IO.Close(F);
exit Reading_Characters;
end if;
Last_Char_Index := Current_Char_Index + Read_Count - 1;
end if;
Char := Buffer(Current_Char_Index);
Current_Char_Index := Current_Char_Index + 1;
if Char = Ctrl_Z then
DOS_IO.Close(F);
exit Reading_Characters;
end if;
if Char in Printable_Chars then
The_Line(I) := Char;
exit Reading_Characters when Char = '.';
else
The_Line(I) := ' ';
end if;
end loop Reading_Characters;
-- if The_Line ends with a partial word, scan back a ways for a
-- blank and break it there instead.
if The_Line(The_Line'Last) /= ' '
and (Current_Char_Index <= Last_Char_Index
and then Buffer(Current_Char_Index) in Visible_Chars) then
Scan_Back_For_Blank:
for I in reverse The_Line'Last-Max_Back_Off .. The_Line'Last-1 loop
if The_Line(I) = ' ' then
Buffer(Current_Char_Index - (The_Line'Last - I)
.. Current_Char_Index - 1)
:= The_Line(I + 1 .. The_Line'Last);
The_Line(I + 1 .. The_Line'Last):=(I+1 .. The_Line'Last => ' ');
Current_Char_Index := Current_Char_Index - (The_Line'Last - I);
exit Scan_Back_For_Blank;
end if;
end loop Scan_Back_For_Blank;
end if;
-- The_Line is ready to display.
-- allow termination or defer requests.
-- if none, put The_Line on the screen
select
accept Premature_Death;
or
accept Defer(How_Long: in Duration) do
Patience := How_Long;
end;
-- request to defer a while to keyboard.
-- continue defering until End_Defer or timeout
Deferring:
loop
select
accept Continue_Deferring; -- just restart Patience delay
or
accept End_Defer; -- immediately quit deferring
exit;
or
delay Patience; -- or wait for Patience timeout
exit;
end select;
end loop Deferring;
else
Screen.Scroller.Put(The_Line);
end select;
end loop Reading_Lines;
-- all done reading lines. Let this task die.
exception
when DOS_IO.Name_Error => -- no such file. Let this task die.
null;
end Read_File;
end Reader;